package com.view;

import java.util.ArrayList;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.view.View;
import android.view.View.OnClickListener;
import android.util.Log;
import com.aybived.AybivedConfig;
import com.aybived.Loader;
import com.aybived.SceneHolder;
import com.aybived.main;
import com.drawables.Animation;
import com.drawables.LevelTile;
import com.drawables.Tscherekta;
import com.interfaces.Updateable;

public class Scene extends GLSurfaceView implements Updateable, Renderer {
	
	private Random rand;
	private LevelTile currentTile1,currentTile2;
	private ArrayList<Bitmap> obstaclesBitmaps;
	private ArrayList<LevelTile> levelTileList;
	private ArrayList<Animation> animations;
	private Tscherekta byvi;
	private Boolean loaded = false;
	private Boolean skip_update = true;
	private Boolean exit = false;
	private Boolean menu_shown = false;
	public float score = 0;
	
	//Constructor
	public Scene(Context context) {
		super(context);
		setRenderer(this);
		rand = new Random();
		
		// parse XML and load Bitmaps
		Loader loader = new Loader(context);
		//obstaclesBitmaps = loader.getObstacleImageList();
		if(!loaded)
			levelTileList = loader.getLevelTilesList();
		//animations = loader.getAnimations();
		//animations.get(0).setFrameRate(12);
		//animations = new ArrayList<Animation>();
		
		byvi = new Tscherekta();
		currentTile1=levelTileList.get(0);
		currentTile2=levelTileList.get(1);
		
	}
	
	public void reset_level() {
		currentTile1.setVisible(false);
		currentTile2.setVisible(false);
		currentTile1 = levelTileList.get(0);
		currentTile1.setPosX(0);
		currentTile1.setVisible(true);
		currentTile2 = levelTileList.get(1);
		currentTile2.setVisible(true);
		currentTile2.setPosX(currentTile1.getMaskWidth());
		
		byvi.reset();
		
		score = 0;
		skip_update = true;
	}
	
	// get a random tile which is not already visible. changes visibility to true
	private LevelTile getRandomTile() {
		LevelTile tmp;
		do{
			tmp = levelTileList.get(rand.nextInt(levelTileList.size()));
		}while(tmp.isTileVisible() || tmp.getLevelStartTag() != currentTile2.getLevelEndTag());

		
		tmp.setVisible(true);
		return tmp;
	}

	public void update(double dt) {

		if(skip_update || exit) // needed so that the game is only starting after the surface displays the 3d context
			return;
		
		score += dt;
		
		currentTile1.update(dt);
		currentTile2.update(dt);
		
		//updating tiles
		if(currentTile1.isOutofBounds()) {
			currentTile1.resetPosition();
			currentTile1 = currentTile2;
			currentTile2 = getRandomTile();
			currentTile2.setPosX(currentTile1.getMaskWidth()+currentTile1.getPosX());
		}

		//updating byvi
		byvi.update(dt);
		
		//palying animation
		//animations.get(0).update(dt);
		
		// collision detection

		int byviPosImageX = (int)(-currentTile1.getPosX() + byvi.posX + byvi.getTextureWidth());
		int byviPosImageY = main.getScreenDimesions()[1] - (int)byvi.posY + byvi.getTextureHeight();
		
		if( currentTile1.checkMaskPixel( byviPosImageX, byviPosImageY + AybivedConfig.CHARACTER_EUNUCHISIEREN ) || // bottom left
		currentTile1.checkMaskPixel( byviPosImageX + byvi.getTextureWidth(), byviPosImageY + AybivedConfig.CHARACTER_EUNUCHISIEREN) || // bottom right
		currentTile1.checkMaskPixel( byviPosImageX, byviPosImageY + byvi.getTextureHeight() - AybivedConfig.CHARACTER_EUNUCHISIEREN ) ||// top left
		currentTile1.checkMaskPixel( byviPosImageX + byvi.getTextureWidth(), byviPosImageY + byvi.getTextureHeight() - AybivedConfig.CHARACTER_EUNUCHISIEREN)) // top right

		{
			exit = true;
		}
		/*
		 *  
		*/
		 
	}
	
	public void resume() {
		reset_level();
		exit = false;
		menu_shown = false;
	}
	
	@Override
	public void onDrawFrame(GL10 gl) {
		
		if(exit && !menu_shown) {
			//main.ref.endGame();
			main.ref.updateHandler.sendEmptyMessage(1);
			menu_shown = true;
		}
		
		gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
		gl.glLoadIdentity();
		
		// creating own unit space
		gl.glPushMatrix();
		
			gl.glTranslatef(-1.0f, -1.0f, 0);
			gl.glScalef(1.0f/(float)main.getScreenDimesions()[0]*2.0f, 1.0f/(float)main.getScreenDimesions()[1]*2.0f, 0);
			
			//drawing tiles
			currentTile1.draw(gl);
			currentTile2.draw(gl);
			
			//drawing byvi
			byvi.draw(gl);
			
			//draw animation caustics
			//animations.get(0).draw(gl);
			
		gl.glPopMatrix();
		
		skip_update = false;
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		//calculate aspect raio:
		GLU.gluPerspective(gl, 45.0f, (float) width / height, -0.1f, 100.0f);
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		gl.glShadeModel(GL10.GL_SMOOTH);
		gl.glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.glClearDepthf(1.0f);
		gl.glEnable(GL10.GL_DEPTH_TEST);
		gl.glDepthFunc(GL10.GL_LEQUAL);

		//creating level tiles with gl-context
		for(int i=0;i<levelTileList.size();i++)
			levelTileList.get(i).loadGlTexture(gl,true);
		
		//loading textures of animations
		//for( int i=0; i<animations.size(); i++)
			//animations.get(i).loadGlTexture(gl);
	
		//loading textures of byvi
		byvi.loadGlTexture(gl,false);
		
		//really nice perspective calculations
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
	}	
	
}
